package com.chj.comp.common.gateway.security.filter;

import com.chj.comp.common.core.constant.CommonConstant;
import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author ：cuihui
 * @date ：Created in 2023/4/2
 * @description：Autho2.0授权码模式、简单模式下的一些特殊处理
 * @modified By：
 */
@Component
@RefreshScope
public class AuthCodeFilter implements GlobalFilter, Ordered {

    @Value("${gateway-path}")
    private String gatewayPath;


    @Override
    public int getOrder() {
        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
    }


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().value();
        // 授权码模式、简单模式请求下面俩地址会重定向，此处特殊处理，拼接网关url头
        if (path.contains(CommonConstant.AUTHORIZE_URI) || path.contains(CommonConstant.LOGIN_URI)) {
            //构建响应包装类
            HttpResponseDecorator responseDecorator = new HttpResponseDecorator(exchange.getRequest(), exchange.getResponse(), gatewayPath);
            return chain
                    .filter(exchange.mutate().response(responseDecorator).build());
        }
        return chain.filter(exchange);
    }
}


class HttpResponseDecorator extends ServerHttpResponseDecorator {

    private String proxyUrl;

    private ServerHttpRequest request;

    /**
     * 构造函数
     *
     * @param delegate
     */
    public HttpResponseDecorator(ServerHttpRequest request, ServerHttpResponse delegate, String proxyUrl) {
        super(delegate);
        this.request = request;
        this.proxyUrl = proxyUrl;
    }

    /**
     * 对于重定向的地址拼接网关url头
     * @param body
     * @return
     */
    @Override
    public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
        HttpStatus status = this.getStatusCode();
        if (status.equals(HttpStatus.FOUND)) {
            String domain = proxyUrl + CommonConstant.AUTH_URI;
            String location = getHeaders().getFirst("Location");
            if(!location.split("\\?")[0].contains(CommonConstant.AUTH_URI)){
                String replaceLocation = location.replaceAll("^((ht|f)tps?):\\/\\/(\\d{1,3}.){3}\\d{1,3}(:\\d+)?", domain);
                if (location.contains("code=")) {

                } else {
                    getHeaders().set("Location", replaceLocation);
                }
            }
        }
        this.getStatusCode();
        return super.writeWith(body);
    }
}
